﻿using BrnMall.Core;
using BrnMall.Manager.Domain.User;
using BrnMall.Manager.Manager.Store;
using BrnMall.Manager.Manager.User;
using BrnMall.WeiXin.Sdk;
using BrnMall.WeiXin.Sdk.Domain;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WeiTap.Web;

namespace BrnMall.Services
{
    /// <summary>
    /// 充值订单操作管理类
    /// </summary>
    public class CashOrders
    {
        static object lockObj = new object();
        /// <summary>
        /// 充值
        /// </summary>
        /// <param name="oid">订单id</param>
        /// <param name="orderState">订单状态</param>
        /// <param name="paySN">支付单号</param>
        /// <param name="payTime">支付时间</param>
        public static void PayOrder(int oid, OrderState orderState, string paySN, DateTime payTime)
        {
            int state = (int)orderState;
            var orderInfo = new CashOrder();
            //是否重复
            lock (lockObj)
            {
                orderInfo = CashOrderManager.Get(oid);
                if (orderInfo == null)
                    return;
                if (orderInfo.OrderState == ((int)OrderState.Confirmed))
                {
                    Trace.TraceInformation(string.Format("CashOrders.cs 页面 微信充值回调，同一单号不能重复充值，参数：订单ID：{0}，订单状态：{1}，支付单号：{2}，支付时间：{3}", oid, state, paySN, payTime));
                    return;
                }
            }

            var storeInfo = Stores.GetStoreById(orderInfo.StoreId);
            var cashInfo = GetUserCash(orderInfo.Uid);
            //新的余额
            decimal cash = DecodeCash(cashInfo.Cash) + orderInfo.OrderAmount + orderInfo.GiveAmount;
            //新的赠送总额
            decimal giveCash = cashInfo.GiveCash + orderInfo.GiveAmount;

            //更新余额
            int cash_count = UserCashManager.UpdateCash(orderInfo.Uid, EncodeCash(cash), giveCash);

            //更改订单状态
            int order_count = CashOrderManager.PayOrder(oid, orderState, paySN, payTime);

            //添加充值记录
            var record = new CashRecord() { Uid = orderInfo.Uid, StoreId = orderInfo.StoreId, Amount = orderInfo.OrderAmount, GiveAmount = orderInfo.GiveAmount, Balance = cash, Direction = 1, remark = "微信充值", CreateTime = DateTime.Now };
            CashRecordManager.Add(record);

            if (cash_count < 1)
                Trace.TraceInformation(string.Format("CashOrders.cs 页面 微信充值回调，余额更新失败，参数：会员ID：{0}，旧余额：{1}，旧赠送总额：{2}，当前订单金额：{3}，订单赠送金额：{4}",
                    orderInfo.Uid, cashInfo.Cash, cashInfo.GiveCash, orderInfo.OrderAmount, orderInfo.GiveAmount));

            if (order_count < 1)
                Trace.TraceInformation(string.Format("CashOrders.cs 页面 微信充值回调，订单更新失败，参数：会员ID：{0}，订单ID：{1},订单状态：{2}，支付单号：{3}，支付时间：{4}", orderInfo.Uid, oid, orderState, paySN, payTime));

            try
            {
                var t = new System.Threading.Thread(() =>
                {
                    SendPaySuccessMessage(orderInfo, storeInfo);
                });
                t.Start();
            }
            catch (Exception e)
            {
                Trace.TraceError($"发送支付通知{e.Message}");
            }
        }

        /// <summary>
        /// 发送客户支付成功模板消息
        /// </summary>
        /// <param name="oid"></param>
        public static void SendPaySuccessMessage(CashOrder orderInfo, StoreInfo storeInfo)
        {
            try
            {
                var prepayId = orderInfo.prepay_id;

                if (string.IsNullOrEmpty(prepayId)) { Trace.TraceInformation("未找到prepayID"); return; }

                var partUserInfo = Users.GetPartUserById(orderInfo.Uid);
                var config = StoreWxAppManager.GetStoreDefaultWxAppById(orderInfo.StoreId, partUserInfo.WeAppId);
                if (storeInfo.StorePid > 0)
                {
                    config = StoreWxAppManager.GetStoreDefaultWxAppById(storeInfo.StorePid, partUserInfo.WeAppId);
                    Trace.TraceInformation("启用平台设置:" + storeInfo.StorePid + "pay:" + config.PaySuccessTid + "deliver:" + config.DeliverSuccessTid);
                }
                if (string.IsNullOrEmpty(config.PaySuccessTid)) { Trace.TraceInformation("支付模板未设置"); return; }

                var accessToken = WeiXinSdk.GetAccessToken(config.WeAppId, config.WeAppSecret);
                if (string.IsNullOrEmpty(accessToken.Access_Token)) { Trace.TraceInformation("获取accessToken失败"); return; }

                var oauth = OAuths.GetOAuthUserByUid(orderInfo.Uid);
                if (oauth == null) return;

                var data = new TemplateData
                {
                    keyword1 = new TemplateKeyWord { value = DateTime.Now.ToShortDateString() },//下单时间
                    keyword2 = new TemplateKeyWord { value = orderInfo.OSN },//订单号码
                    keyword3 = new TemplateKeyWord { value = orderInfo.OrderAmount.ToString("0.00") },//订单金额
                    keyword4 = new TemplateKeyWord { value = orderInfo.OrderAmount.ToString("0.00") },//支付金额
                    keyword5 = new TemplateKeyWord { value = "已支付" }
                };
                SendTemplateMessage.PostPaySuccess(accessToken.Access_Token, oauth.OpenId, config.PaySuccessTid, prepayId, data);
            }
            catch (Exception e)
            {
                Trace.TraceError(e.Message);
            }
        }

        /// <summary>
        /// 发送店铺订单成功支付消息
        /// </summary>
        /// <param name="oid"></param>
        public static void SendStoreOrderPaySuccessMessage(int oid, CashOrder orderInfo, string storeName)
        {
            try
            {
                var uid = Users.GetStoreAdminerIdByStoreId(orderInfo.StoreId);
                if (uid <= 0) return;
                var oauth = OAuths.GetOAuthUserByUid(uid);
                if (oauth == null || !oauth.Server.Equals("dyb", StringComparison.InvariantCultureIgnoreCase)) return;
                var www = new HttpFire($"http://wxopen.711688.com.cn/wxopen/ajax_kf.aspx?action=SendPayMsg&storename={storeName}&username={oauth.OpenId}&osn={orderInfo.OSN}&uid={orderInfo.Uid}&totalprice={orderInfo.OrderAmount}")
                {
                    Method = HttpRequestMethod.Get
                };
                www.GetString();

            }
            catch (Exception e)
            {
                Trace.TraceError($"发送店铺下单消息失败{e.Message}");
            }
        }

        /// <summary>
        /// 扣除账户资金，并添加扣款记录
        /// </summary>
        /// <param name="uid"></param>
        /// <param name="Amount">扣除的余额</param>
        /// <returns></returns>
        public static void ConsumeCash(int uid, int storeId, decimal Amount, string remark)
        {
            //获取余额
            var userCash = UserCashManager.GetInfo(uid);
            if (userCash == null) return;

            decimal cash = DecodeCash(userCash.Cash) - Amount;       //余额=旧余额-交易金额
            if (cash < 0) cash = 0;

            //更新余额
            int cash_count = UserCashManager.UpdateCash(uid, EncodeCash(cash), userCash.GiveCash);
            if (cash_count > 0)
            {
                //添加扣款记录
                if (string.IsNullOrEmpty(remark)) remark = "消费扣款";
                var record = new CashRecord() { Uid = uid, StoreId = storeId, Amount = Amount, GiveAmount = 0, Balance = cash, Direction = 2, remark = remark, CreateTime = DateTime.Now };
                CashRecordManager.Add(record);
            }
            else
            {
                Trace.TraceInformation(string.Format("CashOrders.cs 页面 扣除余额失败，方法：UpdateCash({0},{1},{2})， 单笔金额:{3}", uid, cash, Amount));
            }
        }

        static UserCash GetUserCash(int uid)
        {
            var cashInfo = UserCashManager.GetInfo(uid);
            if (cashInfo == null)
            {
                cashInfo = GetDefaultUserCash(uid);
                UserCashManager.Add(cashInfo);
            }
            return cashInfo;
        }


        /// <summary>
        /// 返回余额为0的实体
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        public static UserCash GetDefaultUserCash(int uid)
        {
            return new UserCash() { id = 0, Uid = uid, Cash = "0", GiveCash = 0 };
        }

        /// <summary>
        /// 加密余额
        /// </summary>
        /// <param name="cash"></param>
        /// <returns></returns>
        public static string EncodeCash(decimal cash)
        {
            return cash.ToString();
        }

        /// <summary>
        /// 解密余额
        /// </summary>
        /// <param name="cash"></param>
        /// <returns></returns>
        public static decimal DecodeCash(string cash)
        {
            return Convert.ToDecimal(cash);
        }
    }
}